package com.globallogic.training.javase.university.schedule;

import com.globallogic.training.javase.university.member.Group;
import com.globallogic.training.javase.university.subject.Activity;

/**
 * This class combines the following classes
 * to construct a schedule for a period of time:
 * 	- DayOfWeek
 * 	- Auditorium
 * 	- Activity (Lecture, Seminar or Exam)
 * @author Ivan Moisiienko
 * @version 0.2 2013/05/13
 */
public class ScheduleCell implements Comparable<ScheduleCell> {

	private DayOfWeek day;
	private int cellNumber;
	private Auditorium auditoriumAssigned;
	private Activity activityAssigned;
	
	/**
	 * @param day Day of week cannot be null
	 * @param cellNumber Cell number should be 
	 * 					 in range 1 .. NUMBER_OF_CELLS_PER_DAY
	 */
	public ScheduleCell(DayOfWeek day, int cellNumber, Auditorium aud) {
		
		if (day == null || cellNumber < 1 
				|| cellNumber > Schedule.NUMBER_OF_CELLS_PER_DAY) {
			
			throw new IllegalArgumentException(
					"Day cannot be null. Cell should be between 1 and " 
					+ Schedule.NUMBER_OF_CELLS_PER_DAY);
		}
		
		this.day = day;
		this.cellNumber = cellNumber;
		this.auditoriumAssigned = aud;
	}
	
	public Auditorium getAuditoriumAssigned() {
		return auditoriumAssigned;
	}
	
	public Activity getActivityAssigned() {
		return activityAssigned;
	}
	
	public void setActivity(Activity act) {
		activityAssigned = act;
	}
		
	public DayOfWeek getDay() {
		return day;
	}

	public int getCellNumber() {
		return cellNumber;
	}
	
	public boolean hasGroup(Group group) {
		if (activityAssigned != null) {
			Group gr = activityAssigned.getGroup();
			if (gr != null && gr.equals(group)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + cellNumber;
		result = prime * result + day.ordinal();
		result = prime * result + auditoriumAssigned.hashCode();
		return result;
	}
	
	@Override
	public boolean equals(Object otherObject) {
		if (this == otherObject) {
			return true;
		}
		if (otherObject == null) {
			return false;
		}
		if (getClass() != otherObject.getClass()) {
			return false;
		}
		
		ScheduleCell other = (ScheduleCell) otherObject;
		if (this.day.equals(other.day) 
				&& this.cellNumber == other.cellNumber
				&& this.auditoriumAssigned.equals(other.auditoriumAssigned)) {
			return true;
		}
		return false;
	}
	
	public String toString() {
		return "Day = " + day + ". Cell = " + cellNumber 
				+ ". Aud = " + auditoriumAssigned + ".";
	}

	@Override
	public int compareTo(ScheduleCell other) {
		DayOfWeek day = this.day;
		DayOfWeek otherDay = other.day;
		int cellNumber = this.cellNumber;
		int otherCellnumber = other.cellNumber;
		int audNumber = auditoriumAssigned.getAuditoriumNumber();
		int otherAudNumber = other.auditoriumAssigned.getAuditoriumNumber();
		
		int dayCompare = day.compareTo(otherDay);
		int cellNumberCompare = cellNumber - otherCellnumber;
		int audCompare = audNumber - otherAudNumber;
		
		if (dayCompare > 0 
				|| (dayCompare == 0 && cellNumberCompare > 0)
				|| (dayCompare == 0 && cellNumberCompare == 0 && audCompare > 0)) {
			return 1;
		}		
		if (dayCompare < 0 
				||(dayCompare == 0 && cellNumberCompare < 0)
				|| (dayCompare == 0 && cellNumberCompare == 0 && audCompare < 0)) {
			return -1;
		}
		return 0;
	}
	
}